#!/bin/bash
# shellcheck source=meta-facebook/meta-yosemite4/recipes-yosemite4/plat-tool/files/yosemite4-common-functions
source /usr/libexec/yosemite4-common-functions

HSC_PATH="/xyz/openbmc_project/inventory/system/board/Yosemite_4_Medusa_Board/MEDUSA_HSC"

dec_to_hex() {
    local decimal=$1
    local hex=""
    local digits="0123456789ABCDEF"

    while [ "$decimal" -gt 0 ]; do
        remainder=$((decimal % 16))
        hex="${digits:remainder:1}$hex"
        decimal=$((decimal / 16))
    done

    # ensure the length of $hex >= 4
    while [ ${#hex} -lt 4 ]; do
        hex="0$hex"
    done

    echo "0x${hex:-0}"
}

get_medusa_type() {
    local hsc_fault_position="$1"
    local medusa_type
    local inventory_path="${HSC_PATH}${hsc_fault_position}_48V"
    medusa_type=$(busctl introspect xyz.openbmc_project.EntityManager \
        "$inventory_path" | grep "\.Type" | awk '{print $4}' | tr -d '"')
    echo "$medusa_type"
}

read_medusa_hsc_module() {
    local bus=$1
    local addr=$2
    local hsc_fault_position=$3
    local medusa_type=$4

    local failure_data="Medusa 48V HSC${hsc_fault_position} Fault"
    local power_rail="${HSC_PATH}${hsc_fault_position}_48V"

    # Read STATUS_CML (0x7E) if XDP710 type
    if [ "$medusa_type" == "XDP710" ]; then
        STATUS_CML=$(i2ctransfer -f -y "$bus" w1@"$addr" 0x7E r1)
        local description="(0x7E) STATUS_CML"
        if [ -n "$failure_data" ]; then
            failure_data="$failure_data, "
        fi
        failure_data+="$description: $STATUS_CML"
    fi

    # Read STATUS_WORD (0x79)
    read -r LOW_BYTE HIGH_BYTE <<< "$(i2ctransfer -f -y "$bus" w1@"$addr" 0x79 r2)"
    STATUS_WORD=$((LOW_BYTE | (HIGH_BYTE << 8) ))
    STATUS_WORD=$(dec_to_hex $STATUS_WORD)
    local description="(0x79) STATUS_WORD"
    if [ -n "$failure_data" ]; then
        failure_data="$failure_data, "
    fi
    failure_data+="$description: $STATUS_WORD"

    # Read other status registers (1 byte each)
    for reg in 0x78 0x7A 0x7B 0x7C 0x7D 0x80; do
        STATUS=$(i2ctransfer -f -y "$bus" w1@"$addr" $reg r1)
        case $reg in
            0x78) name="STATUS_BYTE";;
            0x7A) name="STATUS_VOUT";;
            0x7B) name="STATUS_IOUT";;
            0x7C) name="STATUS_INPUT";;
            0x7D) name="STATUS_TEMPERATURE";;
            0x80) name="STATUS_MFR_SPECIFIC";;
        esac
        description="($reg) $name"
        if [ -n "$failure_data" ]; then
            failure_data="$failure_data, "
        fi
        failure_data+="$description: $STATUS"
    done

    # Send event
    log-create xyz.openbmc_project.State.Power.PowerRailFault --json \
        "{\"POWER_RAIL\": \"$power_rail\", \"FAILURE_DATA\": \"$failure_data\"}"
}

medusa_hsc_fault()
{
    local hsc_fault_position="$1"
    local bus=11
    local hsc_addr=16
    local medusa_type
    medusa_type=$(get_medusa_type "$hsc_fault_position")

    if [ "$medusa_type" = "XDP710" ]; then
        hsc_addr=$((hsc_addr + 1))
    fi
    hsc_addr=$((hsc_addr + hsc_fault_position * 2))

    # Read Medusa HSC module
    read_medusa_hsc_module $bus $hsc_addr "$hsc_fault_position" "$medusa_type"

    local sentinel_dome_slot_present_percentage=50

    echo "Detected HSC fault at position ${hsc_fault_position}, setting fan PWM to 100%."

    if ! set_sentinel_dome_slot_present_percentage "${sentinel_dome_slot_present_percentage}"; then
        exit 1
    else
        exit 0
    fi
}

medusa_hsc_fault "$1"